<?php

class Server
{
    private $serv;
    private $conn = null;
    private static $fd = null;

    public function __construct()
    {
        $this->initDb();
        $this->serv = new swoole_websocket_server("0.0.0.0", 9501);
        $this->serv->set(array(
            'worker_num' => 8,
            'daemonize' => true,//守护进程是否开启
            // 'daemonize' => false,//守护进程是否开启
            'max_request' => 10000,
            'dispatch_mode' => 2,
            'debug_mode' => 1//1轮循模式，收到会轮循分配给每一个worker进程、2 固定模式，根据连接的文件描述符分配worker。这样可以保证同一个连接发来的数据只会被同一个worker处理、3抢占模式，主进程会根据Worker的忙闲状态选择投递，只会投递给处于闲置状态的Worker
        ));

        $this->serv->on('Open', array($this, 'onOpen'));
        $this->serv->on('Message', array($this, 'onMessage'));
        $this->serv->on('Close', array($this, 'onClose'));

        $this->serv->start();

    }

    function onOpen($server, $request)
    {
        echo "新用户 $request->fd 加入。 \n";
    	// var_dump($request);
        // $server->push($req->fd, json_encode(['online_fd'=>$req->fd]));
    }

    public function onMessage($server, $frame)
    {
        //$server->push($frame->fd, json_encode(["hello", "world"]));
        // var_dump($frame);
        $pData = json_decode($frame->data);
        // var_dump($pData);
        $fid = $frame->fd;
        $uid = intval($pData->uid);
        $tid = intval($pData->tid);
        // var_dump($fid);
        // var_dump($frame->fd);
        $data = array();
        if (isset($pData->content)) {
            $tfd = $this->getFd($tid); //获取绑定的fd
            // var_dump($tfd);
            if ($tfd) {//判断用户是否在线
            	$data = $this->add($uid, $tid, $pData->content,1); //保存消息
                // $server->push(intval($tfd), $pData->content); //推送到接收者
            	$server->push(intval($tfd), json_encode($data)); //推送到接收者
            }else {
            	$data = $this->add($uid, $tid, $pData->content,0); //保存消息
            	$server->push($fid, '当前用户不在线');
            }
            // $server->push($fid, json_encode($data)); //推送到接收者
        } else {
            $this->unBind(null,$uid); //首次接入，清除绑定数据
            if ($this->bind($uid, $fid)) {  //绑定fd
                $data = $this->loadHistory($uid, $tid,1); //加载历史记录
            } else {
                $data = array("content" => "无法绑定fd");
            }
            // $server->push($fid, json_encode($data)); //推送到发送者
        }
        $server->push($fid, json_encode($data)); //推送到发送者
    }


    public function onClose($server, $fd)
    {
        $this->unBind($fd);
        echo "connection close: " . $fd. "\n";
    }


    /*******************/
    function initDb()
    {
        $conn = mysqli_connect("47.110.10.142", "taoyi", "xXhmeWXrA256hC5M");
        if (!$conn) {
            die('Could not connect: ' . mysql_error());
        } else {
            $res = mysqli_select_db($conn, "taoyi");
        }
        $this->conn = $conn;
    }

    public function add($uid, $tid, $content,$status)
    {
    	$time = time();
        $sql = "insert into ty_message (uid,tid,content,uid_status,tid_status,created_at) values ($uid,$tid,'$content',1,$status,$time)";
        if ($this->conn->query($sql)) {
            $id = $this->conn->insert_id;
            $data = $this->loadHistory($uid, $tid,2);
            return $data;
        }
    }

    public function bind($uid, $fid)
    {
    	$time = time();
        $sql = "select * from ty_online where uid=$uid";
        $query = $this->conn->query($sql);
        if (!empty(mysqli_fetch_assoc($query))) {
            $sql = "update ty_online set fid = $fid where $uid=$uid";
            if ($this->conn->query($sql)) {
                return true;
            }
        }else {
            $sql = "insert into ty_online (fid,uid,created_at) values ($fid,$uid,$time)";
            if ($this->conn->query($sql)) {
                return true;
            }
        }

    }

    public function getFd($tid)
    {
        $sql = "select * from ty_online where uid=$tid limit 1";
        $row = "";
        if ($query = $this->conn->query($sql)) {
            $data = mysqli_fetch_assoc($query);
            $row = $data['fid'];
        }
        return $row;
    }

    public function unBind($fd, $uid = null)
    {
        if ($uid) {
            $sql = "delete from ty_online where uid=$uid";
        } else {
            $sql = "delete from ty_online where fid=$fd";
        }
        if ($this->conn->query($sql)) {
            return true;
        }
    }

    // public function loadHistory($fid, $tid, $id = null)
    // {
    //     $and = $id ? " and id=$id" : '';
    //     $sql = "select * from msg where ((fid=$fid and tid = $tid) or (tid=$fid and fid = $tid))" . $and;
    //     $data = [];
    //     if ($query = $this->conn->query($sql)) {
    //         while ($row = mysqli_fetch_assoc($query)) {
    //             $data[] = $row;
    //         }
    //     }
    //     return $data;
    // }
    
    public function loadHistory($uid, $tid,$type)
    {
        // $sql = "update ty_message set status = 1 where (uid = $uid and tid = $tid)";
        if ($type == 1) {
            $sql = "update ty_message set tid_status = 1 where (uid = $tid and tid = $uid)";
            $query = $this->conn->query($sql);
        }
        // if ($query = $this->conn->query($sql)) {
            $sql = "select * from ty_message where ((uid = $uid and tid = $tid) or (uid = $tid and tid = $uid))";
            $data = [];
            if ($query = $this->conn->query($sql)) {
                while ($row = mysqli_fetch_assoc($query)) {
                    $data[] = $row;
                }
            }
        // }

        return $data;
    }
}

// 启动服务器
$server = new Server();